/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package simplemetrosystem.view.table;

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EventObject;
import javax.swing.AbstractCellEditor;
import javax.swing.DefaultCellEditor;
import javax.swing.JColorChooser;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import simplemetrosystem.control.EditCommandManager;
import simplemetrosystem.control.ElementManager;
import simplemetrosystem.model.Element.MetroLine;
import simplemetrosystem.model.charlanguage.NameMap;
import simplemetrosystem.view.InformationPane;
import simplemetrosystem.view.table.Exceptions.InformationPanelException;

/**
 *
 * @author Eric Qian
 */
public class AllLineTable extends JTable {

    /**
     * 
     * @param infPane 
     */
    public AllLineTable(InformationPane infPane) {
        super();
        this.infPane = infPane;
        allLineModel = new AllLineModel(infPane);
        this.setModel(allLineModel);
        setRowSelectionAllowed(false);
        setAutoResizeMode(AllLineTable.AUTO_RESIZE_OFF);
        getTableHeader().setReorderingAllowed(false);
        getTableHeader().setResizingAllowed(false);

        setCell();

        setRowHeight(ROW_HEI);

        for (int i = 0; i < getColumnCount(); i++) {
            int with = getPreferredWidthForCloumn(this, i) + 10;
            with = MIN_WIDTH > with ? MIN_WIDTH : with;
            this.getColumnModel().getColumn(i).setPreferredWidth(with);
        }
    }

    private void setCell() {
        this.setDefaultRenderer(Color.class, new ColorTableCellRenderer());
        this.setDefaultEditor(Color.class, new ColorTableCellEditor(infPane, this));
        TableColumn numColumn = columnModel.getColumn(AllLineModel.COL_NUM);
        numColumn.setCellEditor(new AllLineNumCellEditor(infPane));
    }

    private int getPreferredWidthForCloumn(JTable table, int icol) {

        TableColumnModel tcl = table.getColumnModel();
        TableColumn col = tcl.getColumn(icol);
        int c = col.getModelIndex();
        int width = 0;
        int maxw = 0;

        for (int r = 0; r < table.getRowCount(); ++r) {
            TableCellRenderer renderer = table.getCellRenderer(r, c);
            Component comp = renderer.getTableCellRendererComponent(table, table.getValueAt(r, c), false, false, r, c);
            width = comp.getPreferredSize().width;
            maxw = width > maxw ? width : maxw;
        }
        return maxw < MAX_WIDTH ? maxw : MAX_WIDTH;
    }
    private InformationPane infPane;
    private AllLineModel allLineModel;
    private static final int MIN_WIDTH = 75;
    private static final int MAX_WIDTH = 125;
    private static final int ROW_HEI = 50;
}

class AllLineModel extends AbstractTableModel {

    /**
     * 前置条件:Arraylist lines不为null,为时null抛出NewMetroTableException
     * @param frame
     * @param elementManager 
     * @throws simplemetrosystem.model.TableModel.Exceptions.NewMetroTableException
     */
    public AllLineModel(InformationPane infPane) {
        this.infPane = infPane;
        elementManager = ElementManager.getInstance();
        nameMap = NameMap.getInstance();
        editCommandManager = EditCommandManager.getInstance();
        String[] newColumnName = {
            "", nameMap.getName("English Name"), nameMap.getName("Chinese Name"),
            nameMap.getName("Status"), nameMap.getName("Color"),
            nameMap.getName("Stations Number"), nameMap.getName("Stations"),
            nameMap.getName("Edges Number"), nameMap.getName("Edges")
        };

        columnName = newColumnName;
    }

    @Override
    public Class getColumnClass(
            int column) {
        if (column == COL_COLOR) {
            return Color.class;
        } else {
            return String.class;
        }
    }

    public int getRowCount() {
        return elementManager.getLinesSize();
    }

    @Override
    public String getColumnName(int c) {
        return columnName[c];
    }

    public int getColumnCount() {
        return columnName.length;
    }

    @Override
    public boolean isCellEditable(int row, int column) {
        if (column == COL_NUM || column == COL_NAM ||
                column == COL_CNAM || column == COL_COLOR) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        MetroLine aLine = elementManager.getLineAt(rowIndex);
        if (columnIndex == COL_NAM) {
            if (!(aValue.equals("") || aValue == null)) {
                editCommandManager.EditLine(aLine, (String) aValue,
                        aLine.getChineseName(), aLine.getStatus(), aLine.getColor());
            }
        } else if (columnIndex == COL_CNAM) {
            if (!(aValue.equals("") || aValue == null)) {
                editCommandManager.EditLine(aLine, aLine.getName(),
                        (String) aValue, aLine.getStatus(), aLine.getColor());
            }
        } else if (columnIndex == COL_COLOR) {
            editCommandManager.EditLine(aLine, aLine.getName(),
                    aLine.getChineseName(), aLine.getStatus(), (Color) aValue);
        }

    }

    public Object getValueAt(
            int rowIndex, int columnIndex) {
        if (columnIndex == COL_NUM) {
            return rowIndex + 1;
        } else if (columnIndex == COL_NAM) {
            return elementManager.getLineAt(rowIndex).getName();
        } else if (columnIndex == COL_CNAM) {
            return elementManager.getLineAt(rowIndex).getChineseName();
        } else if (columnIndex == COL_STATUS) {
            return nameMap.getName(elementManager.getLineAt(rowIndex).getStatus());
        } else if (columnIndex == COL_COLOR) {
            return elementManager.getLineAt(rowIndex).getColor();
        } else if (columnIndex == COL_STA_NUM) {
            return elementManager.getLineAt(rowIndex).getStationsSize();
        } else if (columnIndex == COL_STA) {
            String output = "";
            MetroLine aLine = elementManager.getLineAt(rowIndex);
            for (int i = 0; i < elementManager.getLineAt(rowIndex).getStationsSize(); i++) {
                output += aLine.getStationAt(i).getDisplayName() + ",";
            }
            return output;
        } else if (columnIndex == COL_EDG_NUM) {
            return elementManager.getLineAt(rowIndex).getEdgesSize();
        } else if (columnIndex == COL_EDG) {
            String output = "";
            MetroLine aLine = elementManager.getLineAt(rowIndex);
            for (int i = 0; i < aLine.getEdgesSize(); i++) {
                output += aLine.getEdgeAt(i).getDisplayName() + ",";
            }
            return output;
        }
        return null;
    }
    private InformationPane infPane;
    private NameMap nameMap;
    private ElementManager elementManager;
    private EditCommandManager editCommandManager;
    private String[] columnName;
    public static final int COL_NUM = 0;
    public static final int COL_NAM = 1;
    public static final int COL_CNAM = 2;
    public static final int COL_STATUS = 3;
    public static final int COL_COLOR = 4;
    public static final int COL_STA_NUM = 5;
    public static final int COL_STA = 6;
    public static final int COL_EDG_NUM = 7;
    public static final int COL_EDG = 8;
}

class AllLineNumCellEditor extends DefaultCellEditor {

    public AllLineNumCellEditor(InformationPane infPane) {
        super(new JTextField());
        this.infPane = infPane;
        elementManager = ElementManager.getInstance();
    }

    @Override
    public Object getCellEditorValue() {
        return null;
    }

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        try {
            infPane.setFocus(InformationPane.LINE, elementManager.getLineAt(row));
        } catch (InformationPanelException ex) {
            ex.printStackTrace();
        }
        return null;
    }
    private InformationPane infPane;
    private ElementManager elementManager;
}

class ColorTableCellEditor extends AbstractCellEditor implements TableCellEditor {

    public ColorTableCellEditor(InformationPane infPane, JTable table) {
        this.infPane = infPane;
        this.table = table;
        nameMap = NameMap.getInstance();

        panel = new JPanel();
        //prepare color dialog;

        colorChooser = new JColorChooser();
        colorDialog = JColorChooser.createDialog(null, nameMap.getName("Color Chooser"),
                false, colorChooser,
                new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        stopCellEditing();
                    }
                },
                new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        cancelCellEditing();
                    }
                });
    }

    public Object getCellEditorValue() {
        return colorChooser.getColor();
    }

    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        colorChooser.setColor((Color) value);
        panel.setBackground((Color) value);

        return panel;
    }

    @Override
    public boolean shouldSelectCell(EventObject anEvent) {
        //start editing
        colorDialog.setVisible(true);
        //tell caller it is ok to select this cell
        return true;
    }

    @Override
    public void cancelCellEditing() {
        //editing is canceled-hide dialog

        colorDialog.setVisible(true);
        super.cancelCellEditing();
    }

    @Override
    public boolean stopCellEditing() {
        //editing is complete-hide dialog

        colorDialog.setVisible(false);
        super.stopCellEditing();
        //tell caller it is ok to use color value
        return true;
    }
    private InformationPane infPane;
    private NameMap nameMap;
    private JTable table;
    private JColorChooser colorChooser;
    private JDialog colorDialog;
    private JPanel panel;
}

class ColorTableCellRenderer extends JPanel implements TableCellRenderer {

    public ColorTableCellRenderer() {
        super();
        color = Color.WHITE;
    }

    public Component getTableCellRendererComponent(
            JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        
        this.setColor((Color) value);
        
        if (hasFocus) {
            setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
        } else {
            setBorder(null);
        }
        return this;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2D = (Graphics2D) g.create();
        g2D.setColor(color);
        g2D.fillRect(0, 0, this.getWidth(), this.getHeight());
    }
    private Color color;

    private void setColor(Color color) {
        this.color = color;
    }
}
/**
class LineListSelectionListener implements ListSelectionListener {

public LineListSelectionListener(InformationPane infPane) {
this.infPane = infPane;
}

public void valueChanged(ListSelectionEvent e) {

if (e.getValueIsAdjusting() == true) {
System.out.println(e.toString());
ListSelectionModel lsm = (ListSelectionModel) e.getSource();
int selectedRow = lsm.getMinSelectionIndex();
if (selectedRow != 0) {
infPane.setHighLight(ElementManager.getInstance().getLineAt(selectedRow));
infPane.getAllLineTablePane().setLine(ElementManager.getInstance().getLineAt(selectedRow));
}
}
}
private InformationPane infPane;
}
 */
